const REQUEST_DELAY = 500;


/**
 * 延迟获取
 * 
 * @param {Object} ops
 * @param {Function} ops.request 请求函数
 * @param {Function} ops.handleResult 格式化结果函数,用在返回到用户调用时
 * @param {String} ops.dataKey 数据key
 * @param {Number} ops.requestDelay 请求延迟时间
 * 
 */
export default class DelayGet {
  static classType = 'DelayGet';
  get classType() {
    return DelayGet.classType;
  }

  data = {}; // 保存缓存数据
  requestQueue = {}; // 请求中
  waitRequest = []; // 等待请求

  // 当前异步对象
  nextPromise = {
    promise: null,
    resolve: null,
    reject: null
  };

  requestDelay = REQUEST_DELAY; // 请求延迟时间
  dataKey = 'id';

  constructor(ops) {
    let self = this;
    self.request = ops.request;
    if (ops.handleResult){
      self.handleResult = ops.handleResult;
    }
    if (ops.dataKey){
      self.dataKey = ops.dataKey;
    }
    if (ops.requestDelay){
      self.requestDelay = ops.requestDelay;
    }
  }

  get(codes = []){
    let self = this;
    let promises = [];
    let result = [];
    for (let code of codes) {
    // 是否已经存在
      if (self.data[code]) {
        result.push(self.data[code]);

      // 已经在请求中
      } else if (self.requestQueue[code]) {
        promises.push(self.requestQueue[code]);
      } else if (!self.waitRequest.includes(code)) {
        self.waitRequest.push(code);
      }
    }

    // 添加已有数据
    promises.push(Promise.resolve(result));

    if (self.waitRequest.length > 0) {
      promises.push(self.getRemoteRequest());
    }
    return Promise.all(promises).then((res) => self.handleResult(res, codes));
  }
  getData(code) {
    return this.data[code];
  }

  getRemoteRequest() {
    let self = this;
    if (self.nextPromise.promise) {
      return self.nextPromise.promise;
    }
    // 创建定时器请求
    setTimeout(() => {
      let startRequest = self.waitRequest;
      self.waitRequest = []; // 清空待请求
      // 开始请求
      let request = self.request(startRequest, self.data)
        .then(self.nextPromise.resolve)
        .catch(self.nextPromise.reject)
        .finally(() => {
          startRequest.forEach(code => {
            // 从请求队列删除
            delete self.requestQueue[code];
          });
        })
        ;
      // 保存到请求队列
      startRequest.forEach(code => {
        self.requestQueue[code] = request;
      });
    }, REQUEST_DELAY);

    self.nextPromise.promise = new Promise((resolve, reject) => {
      self.nextPromise.resolve = resolve;
      self.nextPromise.reject = reject;
    }).then(res => {
      // 清空本次请求
      self.nextPromise = {};
      return res;
    });

    return self.nextPromise.promise;
  }

  handleResult(list, codes) {
    let self = this;
    let result = {};
    list.forEach(item => {
      item?.forEach(dict => {
        let code = dict[self.dataKey];
        if (codes.includes(code))
          result[code] = dict;
      });
    });

    return result;
  };

  formatItem(/* code, data */) {
  }

  request(/* codes, cache */){
    return Promise.resolve([]);
  }

  addData(data = {}){
    Object.assign(this.data, data);
  }
}